package com.haixinga.commbiz.member.filters;

import com.haixinga.commbiz.commons.biz.ITokenService;
import com.haixinga.commbiz.commons.utils.RedisUtil;
import com.haixinga.commbiz.commons.constants.CS;
import com.haixinga.commbiz.member.vo.MemberLoginUserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 使用Filter 比 Intercept 效率更高；
 * 缺点： 无法直接使用spring bean;
 */
public class AuthFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(AuthFilter.class);

    /** 系统所有api集合， 系统启动时进行初始化赋值 */ //TODO 1
    public static final List<Integer> ALL_API_LIST = new ArrayList<>();

    //允许param中传入token的请求地址串
    private static final Set<String> ALLOWS_PARAMS_TOKEN_URLS = new HashSet<>();
    static{
    }

    @Override
    public void init(FilterConfig filterConfig){}

    @Override
    public void destroy() {}

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;

        //判断用户是否登录
        String iToken = request.getHeader(CS.ACCESS_TOKEN_NAME);

        //当token为空 && 当前请求地址允许在parameter中获取token值
        if(StringUtils.isEmpty(iToken) && ALLOWS_PARAMS_TOKEN_URLS.contains(request.getRequestURI())){
            iToken = request.getParameter(CS.ACCESS_TOKEN_NAME);
        }

        if(StringUtils.isEmpty(iToken)){ //当前无token信息: 未登录
            responseNoLogin(response);
            return ;  //断开Filter链
        }

        //获取缓存中当前登录者的[ uid ]
        MemberLoginUserVO currentUserInfo = RedisUtil.getObject(iToken, MemberLoginUserVO.class);
        if(currentUserInfo == null){ //如果redis 中不存在该对象信息
            responseNoLogin(response);
            return ;  //断开Filter链
        }

        //判断当前URL在系统是否注册
        String apiId = null;

//        for (Api api : ALL_API_LIST) {   //TODO 1
//
//            //请求method合法 & uri合法
//            if(     api.getApiMethod().equalsIgnoreCase(request.getMethod()) &&
//                    request.getRequestURI().matches(api.getApiUri())
//            ){
//                apiId = api.getApiId();
//                break;
//            }
//        }

        //查找用户的apiId集合
        List<String> userApiIdList = currentUserInfo.getApiIdList();

        //判断用户 是否存在该权限
//        if(apiId == null || userApiIdList == null || !userApiIdList.contains(apiId)){
//            responseNoLogin(response);
//            return; //断开Filter链
//        }

        //处理token 缓存信息
        ITokenService.processTokenCache(currentUserInfo, iToken);

        //记录请求地址日志
        logger.debug("req: url:{}:{}{}", request.getServerName(), request.getServerPort(), request.getRequestURI());

        //所有验证通过， 进入下一个filter链
        filterChain.doFilter(servletRequest, servletResponse);
    }


    /** 返回 noLogin错误 **/
    private void responseNoLogin(HttpServletResponse response) throws IOException {

        response.setStatus(CS.API_HTTP_STATUS.NO_LOGIN);
        response.getWriter().print("noLogin");
    }

    /** 返回 无权限访问 错误 **/
    private void responsePermissionDenied(HttpServletResponse response) throws IOException {
        response.setStatus(CS.API_HTTP_STATUS.PERMISSION_DENIED);
        response.getWriter().print("PERMISSION_DENIED");
    }


}
